package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanUtils;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.transaction.bean.*;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmInterestAccrualInfo;
import com.jrx.anytxn.transaction.entity.TlGlInterfaceInfo;
import com.jrx.anytxn.transaction.service.IAccountService;
import com.jrx.anytxn.transaction.service.IGlInterfaceService;
import com.jrx.anytxn.transaction.service.ITransferTypeStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @program: anytxn-cf-transaction
 * @description: 累计账户转列策略
 * @author: xiaoyu.jing
 * @date: 2019-11-15 19:31
 **/
@Service
public class AccuAcctTransferTypeStrategy implements ITransferTypeStrategy<AmInterestAccrualInfo> {
    private static final Logger logger = LoggerFactory.getLogger(AccuAcctTransferTypeStrategy.class);


    @Autowired
    private IGlInterfaceService glInterfaceService;
    @Autowired
    private IAccountService accountService;


    /**
     * 累计账户外转列处理 会计状态升级，转表外，五级分类升级
     * @param transferBean
     * @return
     * @throws TxnException
     */
    @Override
    public TransferSaveBean transferOut(TransferBean<AmInterestAccrualInfo> transferBean) throws TxnException {
        AmInterestAccrualInfo accuAcct =  transferBean.getTransferObject();
        logger.info("累计账户外转列accuAcct:{}",BeanUtils.toMap(accuAcct));
        DelqParamBean delqParamBean = transferBean.getDelqParamBean();
        Date bussinessDate = transferBean.getBussinessDate();
        int accountingDays = transferBean.getAccountingDays();
        int nonAccrualDays = transferBean.getNonAccrualDays();
        int classifyDays = transferBean.getClassifyDays();
        TransferSaveBean transferSaveBean = new TransferSaveBean();
        AmInterestAccrualInfo updateAccuAcct = new AmInterestAccrualInfo();
        updateAccuAcct.setId(accuAcct.getId());
        updateAccuAcct.setCustomerId(accuAcct.getCustomerId());
        updateAccuAcct.setTenantId(accuAcct.getTenantId());
        String tempAccountStatus = accuAcct.getAccountingPhase();
        boolean isUpdate = false;

        //五级分类
        String classify = delqParamBean.getDelqClassifyBeanList().stream()
                .filter(bean -> classifyDays >= bean.getClassifyDays())
                .map(DelqClassifyBean::getClassifyType)
                .max(String::compareTo)
                .orElse("0");

        String classifyReversible = delqParamBean.getDelqClassifyBeanList().get(0).getClassifyReversible();
        String beforeStatus = accuAcct.getLoanClassify();

        if(TransBizConstant.YES_FLAG.equals(classifyReversible)){
            //可逆
            //如果与原状态不同则修改
            if (!classify.equals(accuAcct.getLoanClassify())) {
                isUpdate = true;
                updateAccuAcct.setLoanClassify(classify);
                accuAcct.setLoanClassify(classify);
            }
        }else{
            //不可逆 新分类 大于原分类 才修改
            if(Integer.parseInt(classify) > Integer.parseInt(beforeStatus)){
                isUpdate = true;
                updateAccuAcct.setLoanClassify(classify);
                accuAcct.setLoanClassify(classify);
            }
        }

        //应计/非应计，根据交易账户类型获取对应的参数
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(accuAcct.getAccountType());
        logger.info("应计/非应计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqNonAccrualBean), accuAcct.getNonAccrualsFlag());
        //延滞天数>=转列天数 && 允许转列
        if (nonAccrualDays >= delqNonAccrualBean.getTransDays() &&
                TransBizConstant.TRANSFER_FLAG_1.equals(delqNonAccrualBean.getNonAccrualFlag()) &&
                TransBizConstant.NON_ACCRUALS_FLA_0.equals(accuAcct.getNonAccrualsFlag())) {
            isUpdate = true;
            String txnCode = delqNonAccrualBean.getNonTxnCode();
            String taxTxnCode = delqNonAccrualBean.getNonTaxTxnCode();
            updateAccuAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_1);
            //非应计转列   金额为不含税金额、税分开转
            TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest().subtract(accuAcct.getTaxAmt()), txnCode, tempAccountStatus, bussinessDate);
            TlGlInterfaceInfo taxGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest(),accuAcct.getTaxAmt(), taxTxnCode, tempAccountStatus, bussinessDate);
            logger.info("应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
            logger.info("税金应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(taxGlInterfaceInfo));
            Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
            Optional.ofNullable(taxGlInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));

            accuAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_1);
            //1.生成表外累计账户
            AmInterestAccrualInfo nonAccuAcct = accountService.castNonInterestAccrualAccount(accuAcct,bussinessDate);
            transferSaveBean.setSaveAccuAcct(nonAccuAcct);
            //2.更新累计账户的stop_accrual_flag停止计息标志为1-停止计息
            updateAccuAcct.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_1);
            //3.若为利息累计账户，更新max_interest最大利息金额为当前accrual_total_accru_interest已累计总利息。
            if(TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(accuAcct.getAccountType())){
                updateAccuAcct.setMaxInterest(accuAcct.getAccrualTotalAccruInterest());
            }
        }

        //会计状态转列处理，获取转列天数小于延滞天数，取会计状态最大的那个
        DelqAccountBean delqAccountBean = delqParamBean.getDelqAccountBeanList().stream()
                .filter(bean -> bean.getAccountType().contains(accuAcct.getAccountType()))
                .filter(bean -> accountingDays >= bean.getTransferDays())
                .max(Comparator.comparing(DelqAccountBean::getAccountingPhase))
                .orElseThrow(() -> new TxnBizException(ErrorMsgConstant.SYSTEM_PARAMETER_EXISTS));

        String accountingPhase = delqAccountBean.getAccountingPhase();
        logger.info("会计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqAccountBean), accountingPhase);
        //如果允许转列
        if (TransBizConstant.TRANSFER_FLAG_1.equals(delqAccountBean.getTransferFlag())
                && !tempAccountStatus.equals(accountingPhase)
                && TransBizConstant.NON_ACCRUALS_FLA_0.equals(accuAcct.getNonAccrualsFlag())) {
            isUpdate = true;
            String txnCode = delqAccountBean.getTxnCode();
            updateAccuAcct.setAccountingPhase(accountingPhase);
            //会计状态转列   金额为含税金额
            TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest(), txnCode, tempAccountStatus, bussinessDate);
            logger.info("会计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
            Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
        }


        if (isUpdate) {
            transferSaveBean.setUpdateAccuAcct(updateAccuAcct);
            return transferSaveBean;
        }
        return null;
    }

    /**
     * 累计账户内转列出处理 会计状态降级，转应计，五级分类降级
     * @param transferBean
     * @return
     * @throws TxnException
     */
    @Override
    public TransferSaveBean transferIn(TransferBean<AmInterestAccrualInfo> transferBean) throws TxnException {
        AmInterestAccrualInfo accuAcct =  transferBean.getTransferObject();
        logger.info("累计账户内转列accuAcct:{}",BeanUtils.toMap(accuAcct));
        DelqParamBean delqParamBean = transferBean.getDelqParamBean();
        Date bussinessDate = transferBean.getBussinessDate();
        int accountingDays = transferBean.getAccountingDays();
        int nonAccrualDays = transferBean.getNonAccrualDays();
        int classifyDays = transferBean.getClassifyDays();
        String classifyReversible = delqParamBean.getDelqClassifyBeanList().get(0).getClassifyReversible();
        TransferSaveBean transferSaveBean = new TransferSaveBean();
        AmInterestAccrualInfo updateAccuAcct = new AmInterestAccrualInfo();
        updateAccuAcct.setId(accuAcct.getId());
        updateAccuAcct.setCustomerId(accuAcct.getCustomerId());
        updateAccuAcct.setTenantId(accuAcct.getTenantId());
        String tempAccountStatus = accuAcct.getAccountingPhase();
        boolean isUpdate = false;

        //五级分类
        String classify = delqParamBean.getDelqClassifyBeanList().stream()
                .filter(bean -> classifyDays >= bean.getClassifyDays())
                .filter(bean -> bean.getClassifyType().compareTo(accuAcct.getLoanClassify()) <= 0)
                .map(DelqClassifyBean::getClassifyType)
                .max(String::compareTo)
                .orElse("0");

        if(TransBizConstant.YES_FLAG.equals(classifyReversible)){
            //如果与原状态不同则修改
            if (!classify.equals(accuAcct.getLoanClassify())) {
                isUpdate = true;
                updateAccuAcct.setLoanClassify(classify);
                accuAcct.setLoanClassify(classify);
            }
        }

        //应计/非应计，根据交易账户类型获取对应的参数
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(accuAcct.getAccountType());
        logger.info("应计/非应计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqNonAccrualBean), accuAcct.getNonAccrualsFlag());
        //延滞天数<转列天数 && 允许转列
        if (nonAccrualDays < delqNonAccrualBean.getTransDays() &&
                TransBizConstant.NON_ACCRUALS_FLA_1.equals(accuAcct.getNonAccrualsFlag())) {
            isUpdate = true;

            // 表外累计的转回表内 交易码转为T58XXX
            String txnCode = delqNonAccrualBean.getInNonTxnCode();
            String taxTxnCode = delqNonAccrualBean.getInNonTxnCode();

            //表内累计的转表外后转回表内 交易码转为T56XXX
            if("5".equals(accuAcct.getTxnCode().substring(1,2))){
                txnCode = txnCode.substring(0,1)+(Integer.parseInt(txnCode.substring(1))-2000);
                taxTxnCode = taxTxnCode.substring(0,1)+(Integer.parseInt(taxTxnCode.substring(1))-2000);
            }
            updateAccuAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            //将累计账户的交易码从I9XXXX转为I5XXXX
            updateAccuAcct.setTxnCode(accuAcct.getTxnCode().replaceFirst("9","5"));
            //非应计转列   金额为不含税金额、税分开转
            TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest().subtract(accuAcct.getTaxAmt()), txnCode, tempAccountStatus, bussinessDate);
            TlGlInterfaceInfo taxGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest(),accuAcct.getTaxAmt(), taxTxnCode, tempAccountStatus, bussinessDate);
            logger.info("应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
            logger.info("税金应计/非应计状态转列GL流水为:{}", BeanUtils.toMap(taxGlInterfaceInfo));
            Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
            Optional.ofNullable(taxGlInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
            accuAcct.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        }

        //会计状态转列处理，获取转列天数小于延滞天数并且允许转列的参数，取会计状态最大的那个
        DelqAccountBean delqAccountBean = delqParamBean.getDelqAccountBeanList().stream()
                .filter(bean -> bean.getAccountType().contains(accuAcct.getAccountType()))
                .filter(bean -> accountingDays >= bean.getTransferDays())
                .filter(bean -> TransBizConstant.TRANSFER_FLAG_1.equals(bean.getTransferFlag()))
                .filter(bean -> bean.getAccountingPhase().compareTo(accuAcct.getAccountingPhase()) <= 0)
                .max(Comparator.comparing(DelqAccountBean::getAccountingPhase))
                .orElseThrow(() -> new TxnBizException(ErrorMsgConstant.SYSTEM_PARAMETER_EXISTS));

        String accountingPhase = delqAccountBean.getAccountingPhase();
        logger.info("会计状态转列参数为:{},原状态为:{}", BeanUtils.toMap(delqAccountBean), accountingPhase);
        if (!tempAccountStatus.equals(accountingPhase) && TransBizConstant.NON_ACCRUALS_FLA_0.equals(accuAcct.getNonAccrualsFlag())) {
            isUpdate = true;
            String txnCode = delqAccountBean.getTxnCode();
            updateAccuAcct.setAccountingPhase(accountingPhase);
            //会计状态转列   金额为含税金额
            TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(accuAcct, accuAcct.getAccrualTotalAccruInterest(),txnCode, tempAccountStatus, bussinessDate);
            logger.info("会计状态转列GL流水为:{}", BeanUtils.toMap(glInterfaceInfo));
            Optional.ofNullable(glInterfaceInfo).ifPresent(gl -> transferSaveBean.getTlGlInterfaceInfoList().add(gl));
        }

        if (isUpdate) {
            transferSaveBean.setUpdateAccuAcct(updateAccuAcct);
            return transferSaveBean;
        }
        return null;
    }
}
